<template>
  <div class="border border-solid border-el-light z-999!">
    <Toolbar
      class="border-b border-b-solid border-el-light"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      class="overflow-y-hidden"
      :style="{
        'min-height': '200px',
        height: typeof height === 'number' ? `${height}px` : height
      }"
      v-model="valueHtml"
      :defaultConfig="{ ...gEditorConfig, ...editorConfig }"
      :mode="mode"
      @onCreated="handleCreated"
      v-bind="$attrs"
    />
  </div>
</template>

<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import type { IEditorConfig } from '@wangeditor/editor'
import type { AxiosRequestConfig } from 'axios'
import http from '@/http'

interface Props {
  mode: 'default' | 'simple'
  toolbarConfig: Record<string, any>
  editorConfig: Record<string, any>
  height: number | string
  customUploadOptions: FormGlobalWangEditorField['attrs']['customUploadOptions']
}

type InsertFnType = (url: string, alt?: string, href?: string) => void
type ImageElement = { src: string; alt: string; href: string }

const props = defineProps<Props>()

const editorRef = shallowRef()
const valueHtml = defineModel()

onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

let editorImages: string[] = []
const handleCreated = (editor: any) => {
  editorRef.value = editor
  editorImages = editor.getElemsByType('image').map((o: ImageElement) => o.src)
}

const insertImages: string[] = []
const gEditorConfig: Partial<IEditorConfig> = {
  MENU_CONF: {
    insertImage: {
      onInsertedImage(imageNode: ImageElement | null) {
        if (imageNode == null) return
        // const { src, alt, href } = imageNode
        // console.log('src', src)
        // console.log('alt', alt)
        // console.log('href', href)
        insertImages.push(imageNode.src)
      }
    },
    // 配置自定义上传图片
    uploadImage: {
      // 自定义上传图片
      async customUpload(file: File, insertFn: InsertFnType) {
        const options = props.customUploadOptions
        const formData = new FormData()
        if (options.data) {
          for (const [key, value] of Object.entries(options.data)) {
            if (Array.isArray(value)) {
              value.forEach((v) => formData.append(`${key}[]`, v))
            } else {
              formData.append(key, value)
            }
          }
        }

        formData.append(options.fieldname, file, file.name)

        const headers: Record<string, string> = {}
        if (options.headers instanceof Headers) {
          options.headers.forEach((value, key) => (headers[key] = value))
        } else {
          for (const [key, value] of Object.entries(headers)) {
            if (!value) continue
            headers[key] = String(value)
          }
        }

        const config: AxiosRequestConfig = {
          url: options.action,
          method: options.method,
          headers,
          withCredentials: options.withCredentials || false,
          data: formData
        }

        const { data } = await http.request(config)
        if (data) {
          insertFn(data[options.srcModel])
        }
      }
    }
  }
}

defineExpose({
  deleteImage: () => {
    const _editorImages: string[] = editorRef.value
      .getElemsByType('image')
      .map((o: ImageElement) => o.src)
    // editorImages - _editorImages = 需要删除的图片
    const removeImages1 = editorImages.filter((image) => !_editorImages.includes(image))
    // insertImages - _editorImages = 需要删除的图片
    const removeImages2 = insertImages.filter((image) => !_editorImages.includes(image))
    // console.log('editorImages', editorImages)
    // console.log('_editorImages', _editorImages)
    // console.log('insertImages', insertImages)
    // console.log('removeImages1', removeImages1)
    // console.log('removeImages2', removeImages2)
    // console.log('\n\n')
    const removeImages = removeImages1.concat(removeImages2)
    return removeImages
  }
})
</script>

<style scoped lang="scss"></style>
